﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using RayDen.Library.Components.Surface;
using RayDen.Library.Core.Primitives;
using RayDen.Library.Entity.Scene;

namespace RayDen.MaterialManager.Controls
{

    public interface IEditForm<TType>
    {
        string ValueName { get; set; }
        TType Value { get; set; }
    }

    public abstract class BaseFormEditor<TType, TForm> : UITypeEditor
        where TType : new()
        where TForm : Form, IEditForm<TType>, new()
    {

        protected BaseFormEditor()
        {
            TypeDescriptor.AddAttributes(typeof(TType), new EditorAttribute(this.GetType(), typeof(UITypeEditor)));
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            var svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
            var editValue = (TType)value;
            if (svc != null)
            {
                if (editValue == null)
                {
                    editValue = new TType();
                }
                using (var editDialog = new TForm())
                {
                    editDialog.Value = editValue;
                    if (svc.ShowDialog(editDialog) == DialogResult.OK)
                    {
                        editValue = editDialog.Value; // update object
                    }
                }
            }
            return editValue; // can also replace the wrapper object here
        }
    }

    public class ConstTextureInfoEditor : UITypeEditor
    {
        protected ConstTextureInfoEditor()
        {
            TypeDescriptor.AddAttributes(typeof(ConstTextureInfo), new EditorAttribute(this.GetType(), typeof(UITypeEditor)));
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            var svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
            var editValue = (ConstTextureInfo)value;
            if (svc != null && editValue != null)
            {
                using (var editDialog = new EditSpectrumForm() { ValueName = editValue.Name })
                {
                    editDialog.Value = (RgbSpectrum) editValue.Color;
                    if (svc.ShowDialog(editDialog) == DialogResult.OK)
                    {
                        editValue = new ConstTextureInfo()
                        {
                            Name = editDialog.ValueName,
                            Color = (RgbSpectrumInfo) editDialog.Value
                        };
                    }
                }
            }
            return editValue; // can also replace the wrapper object here
        }
    }

    public class SpectrumUIEditor : BaseFormEditor<RgbSpectrum, EditSpectrumForm> { }

    public class ImageTextureInfoUIEditor : BaseFormEditor<ImageTextureInfo, EditTextureForm> { }

    //public class BrdfEditor: BaseFormEditor<SurfaceBsdf, EditSurfaceBsdfForm> {}

    public static class EditorsBootstraper
    {
        public static bool AppStarted = false;
        static EditorsBootstraper()
        {
            TypeDescriptor.AddAttributes(typeof(RgbSpectrum), new EditorAttribute(typeof(SpectrumUIEditor), typeof(UITypeEditor)));
            TypeDescriptor.AddAttributes(typeof(TextureInfo), new EditorAttribute(typeof(ImageTextureInfoUIEditor), typeof(UITypeEditor)));
            TypeDescriptor.AddAttributes(typeof(ImageTextureInfo), new EditorAttribute(typeof(ImageTextureInfoUIEditor), typeof(UITypeEditor)));
            TypeDescriptor.AddAttributes(typeof(ConstTextureInfo), new EditorAttribute(typeof(ConstTextureInfoEditor), typeof(UITypeEditor)));
        }
    }
}
